/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
 */

import { FileSet } from '@ohos/hvigor';
import fse from 'fs-extra';

import { ResToolInputTypeConst } from '../const/build-directory-const.js';
import { ResToolConfigObj } from '../options/configure/restool-config-options.js';
import { FileUtil } from '../utils/file-util.js';
import { RestoolBuilderInterface } from './restool-builder-interface.js';

/**
 * 生成调用restool工具时需要的配置文件内容
 *
 * @since 2022/6/6
 */
export class RestoolConfigBuilder implements RestoolBuilderInterface {
  public inputFiles: FileSet = new FileSet();
  public outputFiles: FileSet = new FileSet();
  public existsResourceDir = false;

  private resToolConfigObj: ResToolConfigObj = {
    configPath: undefined,
    packageName: undefined,
    output: undefined,
    startId: undefined,
    moduleNames: undefined,
    ResourceTable: [],
    applicationResource: undefined,
    moduleResources: [],
    dependencies: [],
    entryCompiledResource: undefined,
    iconCheck: false,
    compression: undefined,
    thread: undefined,
    ignoreResourcePattern: undefined
  };

  getConfigObject(): object {
    return this.resToolConfigObj;
  }

  /**
   * 超纹理功能生成的 opt-compression.json 中的 path 文件路径会过滤不在资源目录中的
   * 资源目录取 resConfig.json 中的 applicationResource, moduleResources, dependencies
   * 分别表示：AppScope/resources，当前模块的资源目录，以及依赖的 har 模块资源目录
   */
  getResourceDir(): string[] {
    if (!this.existsResourceDir) {
      return [];
    }

    const resourceDir = [
      ...this.resToolConfigObj.moduleResources,
      ...this.resToolConfigObj.dependencies,
    ];
    if (this.resToolConfigObj.applicationResource) {
      resourceDir.push(this.resToolConfigObj.applicationResource);
    }
    return resourceDir;
  }

  addInputVariantDir(inputVariantDir: string): RestoolBuilderInterface {
    return this;
  }

  addInputDir(inputDir: string, inputType?: string): RestoolBuilderInterface {
    FileUtil.checkPathLength(inputDir);
    if (inputType) {
      if (!fse.existsSync(inputDir)) {
        return this;
      }
      this.inputFiles.addEntry(inputDir);
      if (inputType === ResToolInputTypeConst.APP) {
        return this.addAppInputDir(inputDir);
      } else if (inputType === ResToolInputTypeConst.MODULE) {
        return this.addModuleInputDir(inputDir);
      } else if (inputType === ResToolInputTypeConst.HAR) {
        return this.addHarInputDir(inputDir);
      }
    }
    return this;
  }

  private addAppInputDir(inputDir: string): RestoolBuilderInterface {
    FileUtil.checkPathLength(inputDir);
    this.existsResourceDir = true;
    this.resToolConfigObj.applicationResource = inputDir;
    return this;
  }

  private addModuleInputDir(inputDir: string): RestoolBuilderInterface {
    FileUtil.checkPathLength(inputDir);
    this.existsResourceDir = true;
    if (this.resToolConfigObj.moduleResources.indexOf(inputDir) === -1) {
      this.resToolConfigObj.moduleResources.push(inputDir);
    }
    return this;
  }

  private addHarInputDir(inputDir: string): RestoolBuilderInterface {
    FileUtil.checkPathLength(inputDir);
    this.existsResourceDir = true;
    if (this.resToolConfigObj.dependencies.indexOf(inputDir) === -1) {
      this.resToolConfigObj.dependencies.push(inputDir);
    }
    return this;
  }

  addJsonFile(jsonFile: string): RestoolBuilderInterface {
    FileUtil.checkPathLength(jsonFile);
    this.resToolConfigObj.configPath = jsonFile;
    this.inputFiles.addEntry(jsonFile, {
      isDirectory: false,
    });
    return this;
  }

  addModulePackName(packName: string): RestoolBuilderInterface {
    this.resToolConfigObj.packageName = packName;
    return this;
  }

  addEntryCompiledResource(inputDir: string): RestoolBuilderInterface {
    FileUtil.checkPathLength(inputDir);
    this.resToolConfigObj.entryCompiledResource = inputDir;
    return this;
  }

  addOutputDir(outputDir: string): RestoolBuilderInterface {
    FileUtil.checkPathLength(outputDir);
    this.resToolConfigObj.output = outputDir;
    this.outputFiles.addEntry(outputDir);
    return this;
  }

  addIdsPath(idsPath: string): RestoolBuilderInterface {
    FileUtil.checkPathLength(idsPath);
    this.resToolConfigObj.ids = idsPath;
    return this;
  }

  addDefinedIds(definedIds: string): RestoolBuilderInterface {
    FileUtil.checkPathLength(definedIds);
    this.resToolConfigObj.definedIds = definedIds;
    return this;
  }

  addDefinedSysIds(definedSysIds: string): RestoolBuilderInterface {
    FileUtil.checkPathLength(definedSysIds);
    this.resToolConfigObj.definedSysIds = definedSysIds;
    return this;
  }

  addResTable(resTable: string): RestoolBuilderInterface {
    FileUtil.checkPathLength(resTable);
    if (this.resToolConfigObj.ResourceTable.includes(resTable)) {
      return this;
    }
    this.resToolConfigObj.ResourceTable.push(resTable);
    this.outputFiles.addEntry(resTable, {
      isDirectory: false,
    });
    return this;
  }

  setIconCheck(enable: boolean): RestoolBuilderInterface {
    this.resToolConfigObj.iconCheck = enable;
    return this;
  }

  setResCompileThread(thread: number | undefined):RestoolBuilderInterface {
    if (thread){
      this.resToolConfigObj.thread = thread;
    }
    return this;
  }

  setIgnoreResourcePattern(ignoreResourcePattern: string[] | undefined):RestoolBuilderInterface {
    if (ignoreResourcePattern && Array.isArray(ignoreResourcePattern)){
      this.resToolConfigObj.ignoreResourcePattern = ignoreResourcePattern;
    }
    return this;
  }

  forceDelete(): RestoolBuilderInterface {
    return this;
  }

  incremental(): RestoolBuilderInterface {
    return this;
  }

  compressImage(): RestoolBuilderInterface {
    return this;
  }

  addOutputBak(outputBak: string): RestoolBuilderInterface {
    return this;
  }

  addModules(modules: string): RestoolBuilderInterface {
    this.resToolConfigObj.moduleNames = modules;
    return this;
  }

  addStartId(startId: string): RestoolBuilderInterface {
    this.resToolConfigObj.startId = startId;
    return this;
  }

  addAppScopeResourcesDir(inputDir: string): RestoolBuilderInterface {
    return this;
  }

  addHarResourcesMap(map: Map<string, string>): RestoolBuilderInterface {
    return this;
  }

  addModuleResourcesMap(map: Map<string, string>): RestoolBuilderInterface {
    return this;
  }

  incrementalCompile(): RestoolBuilderInterface {
    return this;
  }

  addCompression(compression: string): RestoolBuilderInterface {
    this.resToolConfigObj.compression = compression;
    return this;
  }
}
